package thread;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * unsafe的测试类：
 */
public class UnsafeTest {
    public static void main(String[] args) {
        UnsafeAccessor unsafeAccessor = new UnsafeAccessor();
        System.out.println("value的地址为："+unsafeAccessor.valueOffset);
        unsafeAccessor.value =10;
        System.out.println("修改value的地址为："+unsafeAccessor.valueOffset);
    }
}

/**
 * 简单使用一下Unsafe。
 *      注意：【Unsafe.getUnsafe();】我们自己使用unsafe，不能使用这个方法，这个方法会限制使用权限，通过【ClassLoader来限制的】，无法绕过。
 *      所以，我们可以通过反射来获取，具体步骤是。首先：获取【unsafe类的class对象】，之后，【通过反射，获取一个叫”theUnsafe“】的字段。这个字段就是unsafe对象。
 *          最后，通过这个字段，获取unsafe类。目前我只发现了这一种获取unsafe的方法。
 */
class UnsafeAccessor {

    //这样获取对象，会报错。这是通过ClassLoader来限制的，无法绕过。
//    private static final Unsafe unsafe = Unsafe.getUnsafe();

    //--------------------------------------------------------------------
    //获取unsafe的方法，在别的线程中。
    //--------------------------------------------------------------------

    //通过反射可以获取unsafe对象。
    private static final Unsafe unsafe;
    static {
        try {
            //通过反射，拿到Unsafe的class对象，之后拿到这个class对象的一个【final】字段。【theUnsafe】这个字段是unsafe的对象。
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            //获取到这个unsafe对象。
            unsafe = (Unsafe) theUnsafe.get(null);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new Error(e);
        }
    }
    static Unsafe getUnsafe() {
        return unsafe;
    }


    //一些其他的使用。
    static final long valueOffset;

    volatile int value;
    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                    (UnsafeAccessor.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

}
